package cn.javabb.core.base;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 通用Service
 * @author QINB
 * @CreateDate 2018年9月23日 下午6:57:57
 * @since V1.0
 * @see cn.javabb.core.base
 */
public class BaseService<T extends BaseEntity> {
	
    @Autowired
	protected SqlSessionTemplate sqlSessionTemplate;
    public final static String SQLID = "sqlid";
	@Autowired
	protected BaseMapper<T> mapper;

	/***********************
	 * sqlid+map xml中会获取到所有Map里面的参数
	 ************************/
	/**
	 * 查询列表，分页的时候就带分页参数 分页参数 page,size，没有为不分页
	 *
	 * @param map
	 *            必带参数 sqlid
	 * @return
	 */
	public List<T> queryList(Map<String, Object> map) {
		if (!StringUtils.isEmpty(map.get("page")) && !StringUtils.isEmpty(map.get("size"))) {
			PageHelper.startPage(Integer.parseInt(map.get("page") + ""), Integer.parseInt(map.get("size") + ""));
		}
		List<T> queryList = sqlSessionTemplate.selectList((String) map.get(SQLID), map);
		return queryList;
	}

	/**
	 * Description: 分页查询数据
	 * 
	 * @author QINB
	 * @param map
	 * @return
	 */
	public Page<?> queryListPage(JSONObject map) {
		Page<?> p = null;
		if (!StringUtils.isEmpty(map.get("page")) && !StringUtils.isEmpty(map.get("size"))) {
			p = PageHelper.startPage(Integer.parseInt(map.get("page") + ""), Integer.parseInt(map.get("size") + ""));
		} else {
			p = PageHelper.startPage(1, 10);
		}
		sqlSessionTemplate.selectList((String) map.get(SQLID), map);
		return p;
	}
	/**
	 * 
	 * Description: 不分页查询
	 * 
	 * @author QINB
	 * @param map
	 * @return
	 */
	public List<T> queryListNoPage(Map<String, Object> map) {
		List<T> queryList = sqlSessionTemplate.selectList((String) map.get(SQLID), map);
		return queryList;
	}

	/**
	 * 查询单条记录,多条记录会报错，如果不知道多少条记录，用上面的queryList
	 * 
	 * @param map
	 *            必带参数 sqlid
	 * @return
	 */
	public T queryOne(Map<String, Object> map) {
		return sqlSessionTemplate.selectOne((String) map.get(SQLID), map);
	}

	/**
	 * @param map
	 * @return List<Map<?, ?>>
	 */
	public List<Map<?, ?>> queryListMap(Map<String, Object> map) {
		return sqlSessionTemplate.selectList((String) map.get(SQLID), map);
	}
	public Page<?> queryPageByExample(int page,int size,Example ex){
		Page<?> p = PageHelper.startPage(page,size);
		this.mapper.selectByExample(ex);
		return p;
	}
	/*********************** 通用Mapper ****************************/
	/**
	 * 根据ID查询数据
	 * 
	 * @param id
	 * @return
	 */
	public T queryById(String id) {
		return this.mapper.selectByPrimaryKey(id);
	}
	/**
     * 根据ID查询数据
     * 
     * @param id
     * @return
     */
    public T queryById(Integer id) {
        return this.mapper.selectByPrimaryKey(id);
    }
	/**
	 * 查询所有数据
	 * 
	 * @return
	 */
	public List<T> queryAll() {
	    
		return this.mapper.select(null);
	}
	/**
     * 查询所有数据
     * 
     * @return
     */
    public List<T> queryListByExample(Example example) {
        return this.mapper.selectByExample(example);
    }
	/**
	 * 查询一条数据
	 * 
	 * @param record
	 * @return
	 */
	public T queryOne(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		// mapper = (Mapper<T>)SpringUtil.getBean("userMapper");
		return (T) mapper.selectOne(record);
	}

	/**
	 * 根据条件查询列表
	 *
	 * @param record
	 * @return
	 */
	public List<T> queryListByWhere(T record) {
	    return mapper.select(record);
	}
	public List<T> queryListWithOrder(T record) {
		Example example = new Example(record.getClass());
		example.orderBy("createTime").desc();
		return mapper.selectByExample(example);
	}
	public List<T> queryListByIds(Class<T> clazz, String property, List<String> values) {
		Example example = new Example(clazz);
		example.createCriteria().andIn(property, values);
		return (List<T>) mapper.selectByExample(example);
	}

	/**
	 * 分页查询数据列表
	 *
	 * @param page
	 * @param size
	 * @param record
	 * @return
	 */
	public List<T> queryPageListByWhere(String page, String size, T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		if (StringUtils.isEmpty(page)) {
			page = "1";
		}
		if (StringUtils.isEmpty(size)) {
			size = "10";
		}
		PageHelper.startPage(Integer.valueOf(page), Integer.valueOf(size));
		List<T> list = mapper.select(record);
		return new PageInfo<T>(list).getList();
	}

	/**
	 * 分页查询数据列表
	 * 
	 * @param page
	 * @param rows
	 * @param record
	 * @return
	 */
	public Page<T> queryPageByWhere(String page, String rows, T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		if (StringUtils.isEmpty(page)) {
            page = "1";
	}
        if (StringUtils.isEmpty(rows)) {
		rows = "10";
	}
	Page<T> p = PageHelper.startPage(Integer.valueOf(page), Integer.valueOf(rows));
		mapper.select(record);
		return p;
	}

	/**
	 * 新增
	 * 
	 * @param record
	 * @return
	 */
	public Integer insert(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		Date date = new Date();
		record.setCreateTime(date);
		record.setUpdateTime(date);
		return mapper.insert(record);
	}

	/**
	 * 有选择的保存，选择不为null的字段作为插入字段
	 * 
	 * @param record
	 * @return
	 */
	public Integer insertSelective(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		Date date = new Date();
		record.setCreateTime(date);
		record.setUpdateTime(date);
		return mapper.insertSelective(record);
	}

	/**
	 * 批量插入
	 * @param list
	 * @return
	 */
	public Integer insertList(List<T> list) {
		Date date = new Date();
		list.forEach(t -> {
			t.setCreateTime(date);
			t.setUpdateTime(date);
		});
		if (null == list) {
			return 0;
		}
		return mapper.insertList(list);
	}
	/**
	 * 更新
	 * 
	 * @param record
	 * @return
	 */
	public Integer update(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		record.setUpdateTime(new Date()); // 改变更新时间
		return mapper.updateByPrimaryKey(record);
	}

	/**
	 * 保存,有选择性的更新不为null的字段
	 * 
	 * @param record
	 * @return
	 */
	public Integer updateSelective(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		record.setUpdateTime(new Date()); // 改变更新时间
		return mapper.updateByPrimaryKeySelective(record);
	}
	public Integer updateSelectiveNoOther(T record) {
		return mapper.updateByPrimaryKeySelective(record);
	}

	/**
	 * 插入或者保存
	 * @param record
	 * @return
	 */
    public String insertOrUpdate(T record){
		T selectByPrimaryKey = mapper.selectByPrimaryKey(record);
		if (selectByPrimaryKey == null) {
			record.setCreateTime(new Date());
			record.setUpdateTime(new Date());
			mapper.insert(record);
			return "insert";
		} else {
			record.setUpdateTime(new Date());
			mapper.updateByPrimaryKey(record);
			return "update";
		}
	}
	/**
	 * 插入或者保存[非空数据]
	 * @param record
	 * @return
	 */
	public String insertOrUpdateSelective(T record){
		T selectByPrimaryKey = mapper.selectByPrimaryKey(record);
		if (selectByPrimaryKey == null) {
			record.setCreateTime(new Date());
			record.setUpdateTime(new Date());
			mapper.insertSelective(record);
			return "insert";
		} else {
			record.setUpdateTime(new Date());
			mapper.updateByPrimaryKeySelective(record);
			return "update";
		}
	}
    /**
	 * 根据主键删除
	 * 
	 * @param id
	 * @return
	 */
	public Integer deleteById(String id) {
		return this.mapper.deleteByPrimaryKey(id);
	}
	/**
	 * 根据主键删除
	 *
	 * @param id
	 * @return
	 */
	public Integer deleteById(Integer id) {
		return this.mapper.deleteByPrimaryKey(id);
	}
	/**
	 * 批量删除
	 * 
	 * @param clazz
	 * @param property
	 * @param values
	 * @return
	 */
	public Integer deleteByIds(Class<T> clazz, String property, List<String> values) {
		Example example = new Example(clazz);
		example.createCriteria().andIn(property, values);
		return this.mapper.deleteByExample(example);
	}
	public Integer deleteByIds2(Class<T> clazz, String property, List<Integer> values) {
		Example example = new Example(clazz);
		example.createCriteria().andIn(property, values);
		return this.mapper.deleteByExample(example);
	}
	/**
	 * 根据Bean条件删除
	 * 
	 * @param record
	 * @return
	 */
	public Integer deleteByWhere(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		return mapper.delete(record);
	}
	
	/**
	 * 查询总数 Description:
	 * 
	 * @author QINB
	 * @param record
	 * @return
	 */
	public Integer queryCountByWhere(T record) {
		// mapper = getMapperBean((Class<T>) record.getClass());
		return mapper.selectCount(record);
	}

	public Integer queryCountByExample(Example example) {
		return mapper.selectCountByExample(example);
	}

	/**
	 * 查询重复
	 * Description: 
	 *  
	 * @author QINB
	 * @param clazz 实体类
	 * @param notProperty 排除的属性，为空不排除
	 * @param notPropertyValue 排除的属性的值,为空不排除
	 * @param propertyMap 查询重复的属性和值，以键值对应。
	 * @return 重复了就返回true，没有重复就返回false
	 */
	public boolean queryRepeat(Class<T> clazz,String notProperty,Object notPropertyValue,Map<String,Object> propertyMap){
	    Example example = new Example(clazz);
	    Criteria c = example.createCriteria();
		if (!StringUtils.isEmpty(notProperty) && !StringUtils.isEmpty(notPropertyValue)) {
			c.andNotEqualTo(notProperty, notPropertyValue);
		}
	    for(Map.Entry<String, Object> entry : propertyMap.entrySet()){
	        c.andEqualTo(entry.getKey(),entry.getValue());
	      }
	    return this.mapper.selectCountByExample(example)>0?true:false;
	}

}
